package com.hk.manage.login.service.impl;

import com.hk.base.constant.BaseConstant;
import com.hk.base.constant.RabbitConstant;
import com.hk.commons.eunms.SysCode;
import com.hk.commons.serializer.JacksonObjMapper;
import com.hk.commons.session.RedisSessionDAO;
import com.hk.commons.utils.IDGenerator;
import com.hk.commons.utils.SecurityUtil;
import com.hk.commons.vo.ExecuteResult;
import com.hk.dao.manage.user.mapper.ManagerUserMapper;
import com.hk.dao.manage.user.model.ManagerUserDO;
import com.hk.dao.manage.user.vo.ManagerUserLoginVO;
import com.hk.manage.login.bo.LoginBO;
import com.hk.manage.login.bo.ManagerRegisterBO;
import com.hk.manage.login.enums.UserErrorEnum;
import com.hk.manage.login.service.LoginService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.IdGenerator;

import javax.annotation.Resource;

@Service("loginService")
public class LoginServiceImpl implements LoginService {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoginServiceImpl.class);


    @Resource
    private ManagerUserMapper mapper;

    @Resource
    private RabbitTemplate rabbitTemplate;


    @Override
    public ExecuteResult<Void> loginUpdate(LoginBO bo) {
        String username = bo.getUsername();
        String password = bo.getPassword();
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken();
        token.setUsername(username);
        token.setPassword(password.toCharArray());
        try {
            subject.login(token);
            //登录成功后更新用户的最后登录时S间
            mapper.updateLastLoginTime(username);
        } catch (AuthenticationException e) {
            String message = e.getMessage();
            LOGGER.info("【登录失败】:{}", message);
            UserErrorEnum enums = UserErrorEnum.getEnums(message);
            if (null!= enums){
                return new ExecuteResult<>(enums);
            }
            SysCode sysCode = SysCode.getEnums(message);
            return new ExecuteResult<>(sysCode);
        }

        loginMq((ManagerUserLoginVO) subject.getSession().getAttribute(BaseConstant.LOGIN_SESSION_USER));
        return new ExecuteResult<>();
    }

    @Override
    public ExecuteResult<Void> registerInsert(ManagerRegisterBO bo) {
        String code = bo.getCode();
        //验证码
        if (!StringUtils.equals(code, "000000")) {
            return new ExecuteResult<>(SysCode.USER_NOT_LOGIN);
        }
        String userName = bo.getUsername();
        ManagerUserDO user = mapper.getByUsername(userName);
        if (null != user) {
            LOGGER.info("用户已存在");
            return new ExecuteResult<>(UserErrorEnum.LOGIN_ERROR_ENUM);
        }
        String password = bo.getPassword();
        password = SecurityUtil.getEncryptedPassword(password);
        ManagerUserDO managerUser = new ManagerUserDO();
        managerUser.setUsername(userName);
        managerUser.setPassword(password);
        int i = mapper.registerInsert(managerUser);
        if (i != 1) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            LOGGER.error("注册失败！");
            return new ExecuteResult<>(SysCode.ADD_ERROR);
        }
        //异步通知
        return new ExecuteResult<>();
    }

    private void loginMq(ManagerUserLoginVO user){
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(new JacksonObjMapper()));
        rabbitTemplate.convertAndSend(RabbitConstant.TOPIC_EXCHANGE_NAME,RabbitConstant.SEND_MSG_ROUTING_KEY_SMS,user,new CorrelationData(IDGenerator.genShortId()));
        System.out.println("发送消息！！");
    }

}
